package com.ruoyi.shoufang.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.security.*;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.shoufang.domain.*;
import com.ruoyi.shoufang.service.TSfContractService;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.core.web.controller.BaseController;
import sun.misc.BASE64Decoder;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.util.*;

/**
 * TODO
 * 收房服务
 * @author xuda
 * @date 2023/4/24 17:48
 */
@RestController
@RequestMapping("/contract")
public class ContractController extends BaseController{

    @Autowired
    private TSfContractService tSfContractService;
    @Value("${resources.path}")
    private String staticFilePath;

    /**
    * 收房合同查询
    * @return com.ruoyi.common.core.domain.R<java.lang.Object>
    * @author xuda
    * @date 2023/4/24 18:05
    */
    @PostMapping("/searchContractList")
    public R<Object> searchContractList(@RequestBody TSfContract tSfContract, Integer pageNum, Integer pageSize){
        PageHelper.startPage(pageNum, pageSize);
        List<TSfContract> contractList = tSfContractService.searchContractList(tSfContract);
        PageInfo pageInfo = new PageInfo(contractList);
        return R.ok(pageInfo);
    }

    /**
    * 选择房产弹出List列表带分页
    * @return com.ruoyi.common.core.domain.R<java.lang.Object>
    * @author xuda
    * @date 2023/4/25 8:22
    */
    @PostMapping("/searchHouseInfoList")
    public R<Object> searchHouseInfoList(@RequestBody HouseInfo houseInfo, Integer pageNum, Integer pageSize){
        PageHelper.startPage(pageNum, pageSize);
        List<HouseInfo> HouseList = tSfContractService.searchHouseInfoList(houseInfo);
        PageInfo pageInfo = new PageInfo(HouseList);
        return R.ok(pageInfo);
    }

    /**
    * 收房合同录入：下一步 校验合同租约信息等
    * @return com.ruoyi.common.core.domain.R<java.lang.Object>
    * @author xuda
    * @date 2023/4/25 15:50
    */
    @PostMapping("nextSfContract")
    public AjaxResult nextCfContract(@RequestBody SaveSfContractForm saveSfContractForm) {
        return tSfContractService.nextCfContract(saveSfContractForm);
    }

    /**
     * 根据合同租约信息生成相应账期的付款计划信息
     * @param saveSfContractForm
     * @return
     */
    @PostMapping("generatePayMentPlan")
    public R<Object> generatePayMentPlan(@RequestBody SaveSfContractForm saveSfContractForm) {
        return tSfContractService.generatePayMentPlan(saveSfContractForm);
    }

    /**
    * 保存收房合同
    * @return com.ruoyi.common.core.domain.R<java.lang.Object>
    * @author xuda
    * @date 2023/4/28 15:46
    */
    @PostMapping("saveSfContract")
    public R<Object> saveSfContract(@RequestBody SaveSfContractForm saveSfContractForm){
        long start = System.currentTimeMillis();
        tSfContractService.saveSfContract(saveSfContractForm);
        long end = System.currentTimeMillis();
        System.out.println("执行时间为"+(end-start)+"毫秒");
        return R.ok();
    }

    /**
    * 解约协议录入 {改房产状态,改合同状态,改付款单状态,添加解约协议,添加收退钱表,}
    * @return com.ruoyi.common.core.domain.R<java.lang.Object>
    * @author xuda
    * @date 2023/5/3 20:20
    */
   @PostMapping("saveSfTermination")
   public R<Object> saveSfTermination(@RequestBody SaveSfContractForm saveSfContractForm) throws Exception {
       tSfContractService.saveSfTermination(saveSfContractForm);
       return R.ok();
   }

    //base字符串转图片
    @PostMapping("generateSignImg")
    public AjaxResult generateSignImg(@RequestBody SignImgBean signImgBean) throws IOException {
        String base64 = signImgBean.getResultImg();
        String path = signImgBean.getPath();
        BASE64Decoder decoder = new BASE64Decoder();
        base64 = base64.substring(base64.indexOf(",", 1) + 1, base64.length());
        byte[] b = decoder.decodeBuffer(base64);
        for (int i = 0; i < b.length; i++) {
            if (b[i] < 0) {
                b[i] += 256;
            }
        }
        FileOutputStream write = new FileOutputStream(path);
        write.write(b);
        write.flush();
        write.close();
        return AjaxResult.success();
    }

    //生成合同pdf
    @GetMapping("generateContractPdf")
    public void generateContractPdf(SaveSfContractForm saveSfContractForm, HttpServletResponse response) throws Exception {
       //设置响应类型
        response.setContentType("application/pdf");
        //response.addHeader("Content-Disposition" ,"attachment;filename="+ URLEncoder.encode("测试","UTF-8") + ".pdf");
        //获取response字节输出流
        ServletOutputStream os = response.getOutputStream();
        String templateFilePath = staticFilePath+"1.pdf";
        String sign = "sign.jpg";
        String signature = staticFilePath+"1.png";
        Date startDate = saveSfContractForm.getLeaseStartTime();
        Date endDate = saveSfContractForm.getLeaseEndTime();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        Integer startYear = calendar.get(Calendar.YEAR);
        Integer startMonth = calendar.get(Calendar.MONTH);
        Integer startDay = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.setTime(endDate);
        Integer endYear = calendar.get(Calendar.YEAR);
        Integer endMonth = calendar.get(Calendar.MONTH);
        Integer endDay = calendar.get(Calendar.DAY_OF_MONTH);
        BigDecimal totalAmount =
                new BigDecimal(saveSfContractForm.getDepositMoney()).multiply(new BigDecimal(saveSfContractForm.getDepositType()))
                        .add(new BigDecimal(saveSfContractForm.getMonthRent()).multiply(new BigDecimal(saveSfContractForm.getPaymentType())));


        Map<String, String> map = new HashMap<>();
        map.put("1", saveSfContractForm.getOwnerName());
        map.put("2", saveSfContractForm.getOwnerIdCard());
        map.put("3", saveSfContractForm.getSignUserName());
        map.put("4", saveSfContractForm.getSignUserIdCard());
        map.put("5", saveSfContractForm.getPremiseName());
        map.put("6", saveSfContractForm.getHouseName());
        map.put("7", startYear.toString());
        map.put("8", startMonth.toString());
        map.put("9", startDay.toString());
        map.put("10", endYear.toString());
        map.put("11", endMonth.toString());
        map.put("12", endDay.toString());
        map.put("13", saveSfContractForm.getCountMonth().toString());
        map.put("14", totalAmount.toPlainString());
        map.put("15", startYear.toString());
        map.put("16", startMonth.toString());
        map.put("17", startDay.toString());
        map.put("18", startYear.toString());
        map.put("19", startMonth.toString());
        map.put("20", startDay.toString());


        //解决中文显示问题
        BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        //读取模版文件
        PdfReader reader = new PdfReader(templateFilePath);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //PDF对象
        PdfStamper pdfStamper = new PdfStamper(reader, bos);
        //获取pdf模版属性
        AcroFields form = pdfStamper.getAcroFields();
        //设置字体
        form.addSubstitutionFont(base);
        //属性赋值
        for (String key : map.keySet()) {
            form.setField(key, map.get(key));
        }


        Map<String, String> imageData = new HashMap<>();
        imageData.put("21", sign);
        imageData.put("22", signature);
        // 添加图片
        for (String key : imageData.keySet()) {
            int pageNo = form.getFieldPositions(key).get(0).page;
            Rectangle signRect = form.getFieldPositions(key).get(0).position;
            float x = signRect.getLeft();
            float y = signRect.getBottom();
            // 读图片
            Image image = Image.getInstance(imageData.get(key));
            // 获取操作的页面
            PdfContentByte under = pdfStamper.getOverContent(pageNo);
            // 根据域的大小缩放图片
            image.scaleToFit(signRect.getWidth()+50, signRect.getHeight()+50);
            // 添加图片
            image.setAbsolutePosition(x, y);
            under.addImage(image);
        }
        //允许pdf可以被修改
        pdfStamper.setFormFlattening(true);
        pdfStamper.close();
        FileOutputStream fos = new FileOutputStream("a.pdf");
        fos.write(bos.toByteArray());
        fos.flush();
        fos.close();




        PdfReader pdfReader = new PdfReader("a.pdf");

        //FileOutputStream ops = new FileOutputStream("b.pdf");
        BouncyCastleProvider provider = new BouncyCastleProvider();
        Security.addProvider(provider);
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(new FileInputStream(staticFilePath+"server.p12"), "111111".toCharArray());
        String alias = (String) ks.aliases().nextElement();
        PrivateKey pk = (PrivateKey) ks.getKey(alias, "111111".toCharArray());
        Certificate[] chain = ks.getCertificateChain(alias);
        PdfStamper stamper = PdfStamper.createSignature(pdfReader, os, '\0', null);
        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
        Image img = Image.getInstance(sign);
        img.setAbsolutePosition(139.22647F, 126.363235F);
        appearance.setSignatureGraphic(img);
        appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION);
        appearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS);
        appearance.setReason("reason");
        appearance.setLocation("location");
        appearance.setVisibleSignature(new Rectangle(36, 10, 144, 300), 1, "sig");
        ExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256, provider.getName());
        ExternalDigest digest = new BouncyCastleDigest();
        MakeSignature.signDetached(appearance, digest, pks, chain, null, null, null, 0, MakeSignature.CryptoStandard.CMS);

    }
}
